package com.log4j.entity

import com.log4j.appender.TemplateAppender
import org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender
import org.apache.logging.log4j.core.appender.rolling.RolloverStrategy
import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy
import org.apache.logging.log4j.core.config.Node
import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute
import org.apache.logging.log4j.core.config.plugins.PluginElement
import org.apache.logging.log4j.core.config.plugins.PluginNode
import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required
import org.apache.logging.log4j.core.util.Builder
import org.apache.logging.log4j.status.StatusLogger

data class TemplateAppenderBuilder<T : TemplateAppenderBuilder<T>>(

    @field:PluginBuilderAttribute
    var fileName: String? = null,
    @field:PluginBuilderAttribute
    @field:Required
    var filePattern: String? = null,
    @field:PluginBuilderAttribute
    var append: Boolean = true,

    @field:PluginBuilderAttribute
    var locking: Boolean = false,

    @field:PluginElement("Policy")
    @field:Required
    var policy: TriggeringPolicy? = null,

    @field:PluginElement("Strategy")
    var strategy: RolloverStrategy? = null,

    @field:PluginBuilderAttribute
    var advertise: Boolean = false,

    @field:PluginBuilderAttribute
    var advertiseUri: String? = null,

    @field:PluginBuilderAttribute
    var createOnDemand: Boolean = false,

    @field:PluginBuilderAttribute
    var filePermissions: String? = null,

    @field:PluginBuilderAttribute
    var fileOwner: String? = null,

    @field:PluginBuilderAttribute
    var fileGroup: String? = null,

    @field:PluginNode var node: Node? = null

) : AbstractOutputStreamAppender.Builder<T>(), Builder<TemplateAppender> {

    override fun build(): TemplateAppender? {
        if (!isValid) {
            println("isValid = false")
            return null
        }
        val isBufferedIo = isBufferedIo()
        val bufferSize = getBufferSize()

        if (!isBufferedIo && bufferSize > 0) {
            StatusLogger.getLogger()
                .warn("MyAppender '$name': The bufferSize is set to $bufferSize but bufferedIO is not true")
        }

        val layout = getOrCreateLayout()
        val myappender = TemplateAppender(
            this,
            name, layout, isIgnoreExceptions,
            propertyArray, configuration
        )
        return myappender
    }

    override fun getErrorPrefix(): String = "Component"

}